﻿using ComLib.ComFun;
using ComUIControl;
using KeyboardArg;
using KInterfaces;
using KXmlUIControl;
using KXmlUIControl.KControl;
using LogLib;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Button = System.Windows.Forms.Button;
using TextBox = System.Windows.Forms.TextBox;

namespace KFormBase
{
    public partial class KForm : Form
    {
        #region static Fields and Functions
        public static string XmlConfigFolder = "";
        static KForm()
        {
            string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
            directory = directory.Substring(6);
            StaticTypes.SetRootDirectory(directory);
            XmlConfigFolder = directory + @"\config\";
        }

        public static void CreatKeyBoardManager()
        {

        }

        protected static IntPtr GetKeyBoardManagerMainWnd()
        {
            IntPtr[] FindWindows = SearchWindow.Search("KeyboardManager", "FormManager");
            if (FindWindows.Length > 0)
            {
                return FindWindows[0];
            }
            return IntPtr.Zero;
        }
        #endregion

        #region Design Custom Controls

        protected List<Button> BaseButtons = null;
        protected List<Button> Buttons = null;
        protected List<Label> Labels = null;
        protected List<PictureBox> PictureBoxs = null;
        protected List<TextBox> TextBoxs = null;
        protected List<Image> Images = null;
        protected List<Panel> Panels = null;
        protected List<KCheckBox> CheckBoxs = null;
        protected List<XmlGroupObject> Groups = null;
        protected Dictionary<string, XmlPromptObject> DicPrompts = new Dictionary<string, XmlPromptObject>();
        protected Button buttonNext = null;
        protected Button buttonBack = null;
        protected Button buttonCancel = null;
        protected CountdownControl countdownControl1 = null;
        public int CountdownSecond { get; protected set; } = 0;
        public bool CountdownEnabled { get; private set; }
        protected Dictionary<string, KeyBoardArgs> TextBoxBindings = null;
        protected TextMapService textMapService = null;
        public bool ContainsGroup
        {
            private set;
            get;
        }
     
        protected string _xmlConfigFile = "";

        protected XmlFormObject _formConfig = null;

        protected XmlConfigForm UIConfig = null;

        protected List<XmlModuleObject> Modules = null;

        protected List<XmlProgramObject> Programs = null;

        protected string _appName = "";
        public string AppName
        {
            get
            {
                if (string.IsNullOrEmpty(_appName))
                {
                    _appName = Path.GetFileNameWithoutExtension(this.GetType().Assembly.CodeBase);
                }
                return _appName;
            }
        }

        public string LanguageCode = "";

        public bool IsMainForm { protected set; get; } = true;

        /// <summary>
        /// 最新错误信息
        /// </summary>
        public string Error { get; protected set; }

        /// <summary> 
        /// 设计器支持所需的方法: 执行创建自定义控件以及控件布局
        /// </summary>
        protected void InitializeCustomComponent()
        {
            Error = "";
            Log.WriteAsync("InitializeCustomComponent in");
            SetStyles();
            //this.Controls.Clear();
            this.SuspendLayout();
            _appManager = ModuleAppManager.Instance;
            if (IsMainForm)
            {
                UIConfig = _appManager.AppConfig.MainFormConfig;
            }
            else
            {
                UIConfig = _appManager.AppConfig.ChildFormConfig;
            }
            UIConfig.ParentContainer = this;
            ContainsGroup = UIConfig.ContainsGroup;
            Panels = UIConfig.CreatPanels();
            BaseButtons = UIConfig.CreatBaseButtons();
            Buttons = UIConfig.CreatButtons();
            TextBoxs = UIConfig.CreatTextBoxs();
            Labels = UIConfig.CreatLabels();
            PictureBoxs = UIConfig.CreatPictureBoxs();
            TextBoxBindings = UIConfig.InputtingBindings;
            Images = UIConfig.LoadImages();
            DicPrompts = UIConfig.LoadPrompts();
            countdownControl1 = UIConfig.CreatCountdownControl();
            if (ContainsGroup)
            {
                Groups = UIConfig.Groups;
                CheckBoxs = UIConfig.CreatKCheckBoxs();
            }
            this.SuspendLayout();
            if (TextBoxs != null && TextBoxs.Count > 0)
            {
                textMapService = new TextMapService(TextBoxs, TextBoxBindings);
            }
            foreach (Panel panel in Panels)
            {
                this.Controls.Add(panel);
            }
            foreach (Label lab in Labels)
            {
                this.Controls.Add(lab);
            }
            foreach (TextBox tb in TextBoxs)
            {
                this.Controls.Add(tb);
            }
            foreach (Button btn in BaseButtons)
            {
                this.Controls.Add(btn);
            }
            foreach (Button btn in Buttons)
            {
                this.Controls.Add(btn);
            }
            foreach (PictureBox pic in PictureBoxs)
            {
                this.Controls.Add(pic);
            }
            if (ContainsGroup)
            {
                foreach (KCheckBox cbox in CheckBoxs)
                {
                    this.Controls.Add(cbox);
                }
            }
            //foreach (Control ctl in UIConfig.Controls)
            //{
            //    this.Controls.SetChildIndex(ctl, 0);
            //}
            foreach (PictureBox pic in PictureBoxs)
            {
                ((System.ComponentModel.ISupportInitialize)(pic)).EndInit();
            }
            this.Controls.Add(countdownControl1);
            this.ResumeLayout(false);
            this.PerformLayout();
            XmlFormObject formConfigs = UIConfig.FormConfig;
            formConfigs.SetValues(this);
            Log.WriteAsync("InitializeCustomComponent out");
        }

        protected Control GetControl<T>(string name)
        {
            Type type = typeof(T);
            foreach (Control ctl in Controls)
            {
                if (ctl.GetType() == type)
                {
                    if (ctl.Name.Equals(name))
                    {
                        return ctl;
                    }
                }
            }
            return null;
        }

        public void SetStyles()
        {
            this.DoubleBuffered = true;//设置本窗体
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
        }
        #endregion

        #region Common Fields and Functions
        /// <summary>
        /// 父窗口句柄
        /// </summary>
        protected IntPtr ParentFormHandle = IntPtr.Zero;

        protected ModuleAppManager _appManager = null;

        /// <summary>
        /// 当前应用程序
        /// </summary>
        protected ModuleApplication _currentApp = null;

        protected Dictionary<string, UserControl> DicPages = new Dictionary<string, UserControl>();

        protected ModulePage CurrentPage = null;

        protected ShareData CurrentShareData
        {
            get
            {
                if (_currentApp != null)
                {
                    return _currentApp.SharedData;
                }
                return null;
            }
        }

        public IPageProcess CurrentProcess
        {
            get
            {
                IPageProcess p = CurrentPage.MainPageProcess;
                if (!IsMainForm)
                {
                    p = CurrentPage.ChildPageProcess;
                }
                return p;
            }                 
        }

        public UserControl PageControl
        {
            get
            {
                UserControl frmNew = null;
                if (DicPages.TryGetValue(CurrentPage.SID, out frmNew))
                {
                    return frmNew;
                }
                if (IsMainForm)
                {
                    frmNew = CurrentPage.CreatOrGetMainPageInstance(_currentApp.LanguageCode);
                    DicPages.Add(CurrentPage.SID, frmNew);
                    return frmNew;
                }
                else
                {
                    frmNew = CurrentPage.CreatOrGetChildPageInstance(_currentApp.LanguageCode);
                    DicPages.Add(CurrentPage.SID, frmNew);
                    return frmNew;
                }
            }
        }

        public KForm()
        {
            InitializeComponent();
        }

        public KForm(bool isMainForm):this()
        {
            IsMainForm= isMainForm;
        }

        public void Init(
            EventHandler handlerExit,
            EventHandler handlerRequestExit,
            TakeAdministratorActionEventHandler takeAdminAction,
            JobStateChangedEventHandler stateChanged)
        {
            _appManager.AddAppsEventHandler(
                    OnModulePageChanged,
                    OnModuleAppSwitched,
                    handlerExit,
                    handlerRequestExit,
                    takeAdminAction,
                    stateChanged);
        }

        /// <summary>
        /// 启动新的业务流程
        /// </summary>
        protected void StartNewJob(string name, string tid,string inParams = "")
        {
            _currentApp.StartNew(name, tid, inParams);
        }

        protected void SwitchToModule(ModuleApplication newApp)
        {
            if (_currentApp != null)
            {
                _currentApp.SharedData.ClearValue();
            }
            _currentApp = newApp;
            _currentApp.Restart();
        }

        protected void GoToPage(ModulePage newPage)
        {
            if (this.InvokeRequired)
            {
                Action<ModulePage> handler
                    = new Action<ModulePage>(GoToPage);      
                this.Invoke(handler, new object[] { newPage});
                return;
            }
            Error = "";
            try
            {           
                if (newPage == null)
                {
                    Error = "给定的流程元素对象为空";
                    Log.WriteAsync(Error);
                    MsgBox.Show(Error);
                    return;
                }              
                CurrentPage = newPage;
                if (newPage == _currentApp.HomePage)
                {
                    CurrentShareData.ClearValue();
                }     
                if (!CurrentPage.Available)
                {
                    Error = "流程模块不存在或者不可用。";
                    Log.WriteAsync(Error);
                    MsgBox.Show(Error);
                    return;
                }
                Log.WriteAsync("NowPage:" + CurrentPage.FullFileName);
                UserControl frmNew = PageControl;
                if (frmNew == null)
                {
                    Error = "创建窗体失败:" + CurrentPage.Error;
                    Log.WriteAsync(Error);
                    MsgBox.Show(Error);                    
                    return;
                }
                //清除旧窗体
                this.Controls.Clear();
                //显示新窗体
                frmNew.Dock = DockStyle.Fill;
                frmNew.Show();
                frmNew.Focus();                
                this.Controls.Add(frmNew);                
                InitNewPage();
            }
            catch (Exception ex)
            {
                Error = $"打开页面{newPage.MainPageType.FullName}发生了异常: \n{ex.Message}";
                Log.WriteAsync(Error);
                Log.WriteException(ex.ToString());
                MsgBox.Show(Error);                
            }
        }

        private void InitNewPage()
        {
            if (CurrentPage == null)
            {
                return;
            }
            //IPageProcess p = CurrentProcess;
            //p.SD = _currentApp.SharedData;
            //p.Job = _currentApp.CurrentJob;
            RegisterEventsToPageProcess();
            //p.InitData();
            //p.PlayWelcomeVoice();
            //p.StartWork();                     
        }

        private void RegisterEventsToPageProcess()
        {
            IPageProcess p = CurrentPage.MainPageProcess;
            if (!IsMainForm)
            {
                p = CurrentPage.ChildPageProcess;
            }
            //p.RemoveEvents();
            //p.ModuleSwitched += _currentApp.OnModuleSwitched;
            //p.ModuleChanged += _currentApp.OnModuleChanged;
            //p.PageChanged += _currentApp.OnPageChanged;
            //p.PageSwitched += _currentApp.OnPageSwitched;
            //p.TakeAdminAction += _currentApp.TakeAdministratorAction;
            //p.LanguageChanged += _currentApp.OnLanguageChanged;
            p.RequestMsgSent += OnClientRequestSent;
        }

        protected void OnModulePageChanged(Object sender, ModulePageChangedEventArgs e)
        {
            GoToPage(e.Value);
        }

        protected void OnModuleAppSwitched(Object sender, ModuleAppSwitchedEventArgs e)
        {
            SwitchToModule(e.Value);
        }

        protected virtual void OnClientRequestSent(Object sender, ClientRequestSentEventArgs e)
        {

        }
        #endregion
    }
}


//protected bool LoadFromConfig()
//{
//    _xmlConfigFile = string.Format(@"{0}{1}.xml", XmlConfigFolder, this.AppName);
//    if (!File.Exists(_xmlConfigFile))
//    {
//        Error = $"XmlConfigFile={_xmlConfigFile} is not exists.";
//        Log.WriteAsync(Error);
//        return false;
//    }
//    XmlPageReader reader = new XmlPageReader(_xmlConfigFile);
//    if (reader.TryLoadFormConfig(IsMainForm, out _configForm))
//    {
//        return true;
//    }
//    else
//    {
//        Error = reader.Error;
//        Log.WriteAsync(Error);
//        return false;
//    }
//}

